#ifndef _ORB_H
#define _ORB_H

#include <opencv2/opencv.hpp>
#include "anms.h"
#include <mutex>
#include "FastWrapper.hpp"
namespace markerAR
{
  class  ORB
  {
  public:
    // the size of the signature in bytes
    enum { kBytes = 32, HARRIS_SCORE = 0, FAST_SCORE = 1 };
    
    ORB(int fastThreshold = 10,int _nfeatures = 500, float _scaleFactor = 1.2f, int _nlevels = 8, int _edgeThreshold = 31,
        int _firstLevel = 0, int _WTA_K = 2, int _scoreType = ORB::FAST_SCORE, int _patchSize = 31) :
      nfeatures(_nfeatures), scaleFactor(_scaleFactor), nlevels(_nlevels),
    edgeThreshold(_edgeThreshold), firstLevel(_firstLevel), WTA_K(_WTA_K),
    scoreType(_scoreType), patchSize(_patchSize)
    {
//      fd = FastFeatureDetector(20, true);
//      anms = new ANMS(imgSize);
        fd = FastWrapper(fastThreshold);
    };
    
    // returns the descriptor size in bytes
    int descriptorSize() const ;
    // returns the descriptor type
    int descriptorType() const ;
    
    // Compute the ORB features and descriptors on an image
      void operator()(cv::InputArray image, cv::InputArray mask, std::vector<cv::KeyPoint>& keypoints) ;
    
    // Compute the ORB features and descriptors on an image
    void operator()(cv::InputArray image, cv::InputArray mask, std::vector<cv::KeyPoint>& keypoints,
                    cv::OutputArray descriptors, bool useProvidedKeypoints = false) ;
    void detect(const Mat& image, vector<KeyPoint>& keypoints, const Mat& mask = Mat()) ;
    void compute(const Mat& image, std::vector<KeyPoint>& keypoints, Mat& descriptors) ;
    cv::AlgorithmInfo* info() const;
    
  private:
//    Ptr<ANMS> anms;
    void computeImpl(const cv::Mat& image, std::vector<cv::KeyPoint>& keypoints, cv::Mat& descriptors) ;
    void detectImpl(const cv::Mat& image, std::vector<cv::KeyPoint>& keypoints, const cv::Mat& mask = cv::Mat()) ;
    void computeKeyPoints(const std::vector<cv::Mat>& imagePyramid,
                          const std::vector<cv::Mat>& maskPyramid,
                          std::vector<std::vector<cv::KeyPoint> >& allKeypoints,
                          int nfeatures, int firstLevel, double scaleFactor,
                          int edgeThreshold, int patchSize, int scoreType);
//    bool doAnms;
//    cv::FastFeatureDetector fd;
    int nfeatures;
    double scaleFactor;
    int nlevels;
    int edgeThreshold;
    int firstLevel;
    int WTA_K;
    int scoreType;
    int patchSize;
    std::mutex m;
    FastWrapper fd;
  };
}


#endif